/*
 * QE3e Qt Quick 3D Engine.
 * Copyright (C) 2010 Joris Vaillant and Mathieu Pujol
 * <joris.vaillant@gmail.com>  <mathieu.pujol87@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef QE3E_ITEM
#define QE3E_ITEM

// export
#include <qe3e_global.h>

// includes
// qe3e
#include "Material.h"
#include "Transform.h"
#include "BoundingSphere.h"
#include "Flags.h"
#include <ItemFx.h>

// Qt4
#include <QObject>
#include <QVector3D>
#include <QVector>
#include <QList>

namespace qe3e
{
  // forward declartion
  class Scene;
  class Camera;

  class QE3E_EXPORT Item : public QObject
  {
  public:
    Item(Item* parent = 0);

    void setParent(Item* parent);
    Item* parent() const;

    virtual const QVector<Item*>& childItems() const;
    virtual const QVector<Item*>& drawItems(const Camera& camera) const;

    QVector<Item*> collidingItems() const;

    bool collidesWithItem(const Item* item);

    void addChild(Item* child);
    void removeChild(Item* child);
    void removeChild(int pos);

    bool childExist(Item* child) const;
    int childCount() const;

    void translate(qreal posX, qreal posY, qreal posZ);
    void translate(const QVector3D& trans);

    void setTranslation(qreal posX, qreal posY, qreal posZ);
    void setTranslation(const QVector3D& trans);

    //void setPos(double posX, double posY, double posZ);
    //void setPos(const QVector3D& pos);
   // const QVector3D& pos();

    //void rotate(double rotX, double rotY, double rotZ);
    //void rotate(const QVector3D& rot);

    //void setRotation(double rotX, double rotY, double rotZ);
    //void setRotation(const QVector3D& rot);
    //const QVector3D& rotation() const;

    void rotate(qreal angle, qreal x, qreal y, qreal z);
    void rotate(qreal angle, const QVector3D & axis);

    void scale(qreal sFactor);
    void scale(qreal scaleX, qreal scaleY, qreal scaleZ);
    void scale(const QVector3D& scale);

   // void setScale(double scaleX, double scaleY, double scaleZ);
   // void setScale(const QVector3D& scale);
   // const QVector3D& scale() const;

    void setData(const QString& key, const QVariant& data);
    QVariant data(const QString& key) const;

    void setVisible(bool visible);
    bool isVisible() const;

    void setTransparency(bool enable=true);
    bool isTransparency() const;

    void setPriority(double prio);
    double priority() const;

    void setCollidingEnabled(bool enabled);
    bool isCollidingEnabled() const;

    void setTransform(const Transform& trans);
    const Transform& transform() const;

    const Transform& worldTransform() const;

    void setMaterial(const Material& mat);
    const Material& material() const;
    Material& material();

    void setScene(Scene* scene);
    void setSceneNoCheck(Scene* scene);
    Scene* scene() const;

    void addItemFx(ITEM_FX_ID id);
    void removeItemFx(ITEM_FX_ID id);
    ITEM_FX_ID getItemFxId() const;

    virtual void drawGeometry() const;

    virtual const BoundingSphere& boundingSphere() const;

    const QList<int> & getLightDescriptorIndex() const;

    /*
    virtual bool isGroup() const;
    virtual bool isMesh() const;
    virtual bool isImplicit() const;
    virtual bool isLight() const;
*/

    bool isDirty() const;
    void setDirty(DirtyFlags dirty);
    void addDirty(DirtyFlags dirty);
    void reComputeWorldTransform();

  protected:
    virtual void calcBoundingSphere();

  protected:

    Item* m_parent;
    QVector<Item*> m_children;
    Scene* m_scene;

    Transform m_transform;
    Transform m_worldTransform;

    BoundingSphere m_boundSphere;

    Material m_material;
    bool m_transparency;
    bool m_visible;

    double m_priority;
    int m_dirty; //< DirtyFlags

    ITEM_FX_ID m_itemFxId;
    QList<int> m_lightDescriptorIndex;
  };
}

#endif // QE3E_ITEM
